package com.example.geoaimavlink_android.activity.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import com.example.geoaimavlink_android.R
import com.geoai.mavlink.geoainet.rtk.component.CmccRtkManager
import com.geoai.mavlink.geoainet.rtk.component.NtripClientRtkManager
import com.geoai.mavlink.geoainet.rtk.component.QxRtkManager
import com.geoai.mavlink.geoainet.rtk.component.SixentsRtkManager
import com.geoai.mavlink.geoainet.rtk.component.account.CmccAccount
import com.geoai.mavlink.geoainet.rtk.component.account.NtripClientAccount
import com.geoai.mavlink.geoainet.rtk.component.account.QxAccount
import com.geoai.mavlink.geoainet.rtk.component.account.SixentsAccount
import com.geoai.mavlink.geoainet.rtk.enums.RtkComponentType
import com.google.android.material.switchmaterial.SwitchMaterial
import kotlinx.android.synthetic.main.frag_rtk.btn_component_refresh
import kotlinx.android.synthetic.main.frag_rtk.btn_rtk_connect
import kotlinx.android.synthetic.main.frag_rtk.btn_rtk_disconnect
import kotlinx.android.synthetic.main.frag_rtk.btn_rtk_enable_refresh
import kotlinx.android.synthetic.main.frag_rtk.btn_save_account
import kotlinx.android.synthetic.main.frag_rtk.ll_account
import kotlinx.android.synthetic.main.frag_rtk.rb_rtk_type_cmcc
import kotlinx.android.synthetic.main.frag_rtk.rb_rtk_type_custom
import kotlinx.android.synthetic.main.frag_rtk.rb_rtk_type_none
import kotlinx.android.synthetic.main.frag_rtk.rb_rtk_type_qx
import kotlinx.android.synthetic.main.frag_rtk.rb_rtk_type_sixents
import kotlinx.android.synthetic.main.frag_rtk.rg_rtk_component
import kotlinx.android.synthetic.main.frag_rtk.sw_rtk_enable
import kotlinx.android.synthetic.main.frag_rtk.tv_rtk_state

class RtkFragment: BaseFragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return View.inflate(context, R.layout.frag_rtk, null)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initSDK()
        initView()
    }

    private fun initView() {
        btn_rtk_enable_refresh.setOnClickListener {
            refreshRtkEnable(getProduct()?.rtkManager?.rtkEnable ?: false)
        }
        btn_component_refresh.setOnClickListener {
            getProduct()?.rtkManager?.rtkComponentType?.let { rtkType ->
                refreshRtkComponentType(rtkType)
                refreshAccountView(rtkType)
            }
        }
        sw_rtk_enable.setOnClickListener {
            getProduct()?.rtkManager?.setRtkEnable((it as SwitchMaterial).isChecked) { error ->
                showToast(error?.description?:"success")
            }
        }
        rg_rtk_component.setOnCheckedChangeListener { _, checkedId ->
            val rtkType = when (checkedId) {
                R.id.rb_rtk_type_none -> RtkComponentType.NONE
                R.id.rb_rtk_type_cmcc -> RtkComponentType.CMCC
                R.id.rb_rtk_type_sixents -> RtkComponentType.SIXENTS
                R.id.rb_rtk_type_qx -> RtkComponentType.QX
                R.id.rb_rtk_type_custom -> RtkComponentType.CUSTOM
                else -> {RtkComponentType.NONE}
            }
            getProduct()?.rtkManager?.rtkComponentType = rtkType
            refreshAccountView(rtkType)
            showToast("success")
        }
        btn_rtk_connect.setOnClickListener {
            getProduct()?.rtkManager?.connectRTK {
                showToast(it?.description?:"success")
            }
        }
        btn_rtk_disconnect.setOnClickListener {
            getProduct()?.rtkManager?.disconnectRTK()
        }
        btn_save_account.setOnClickListener {
            kotlin.runCatching {
                when (getProduct()?.rtkManager?.rtkComponentType) {
                    RtkComponentType.NONE -> {}
                    RtkComponentType.CUSTOM -> {
                        val ntripClientRtkManager =
                            getProduct()?.rtkManager?.netWorkRtkManager as NtripClientRtkManager
                        //这里小心处理映射关系
                        ntripClientRtkManager.setAccount(
                            NtripClientAccount(
                                (ll_account.getChildAt(0) as EditText).text.toString(),
                                (ll_account.getChildAt(3) as EditText).text.toString().toInt(),
                                (ll_account.getChildAt(4) as EditText).text.toString(),
                                (ll_account.getChildAt(2) as EditText).text.toString(),
                                (ll_account.getChildAt(1) as EditText).text.toString()
                            )
                        )
                    }

                    RtkComponentType.CMCC -> {
                        val cmccRtkManager =
                            getProduct()?.rtkManager?.netWorkRtkManager as CmccRtkManager
                        cmccRtkManager.setAccount(CmccAccount((ll_account.getChildAt(0) as EditText).text.toString()))
                    }

                    RtkComponentType.QX -> {
                        val qxRtkManager =
                            getProduct()?.rtkManager?.netWorkRtkManager as QxRtkManager
                        qxRtkManager.setAccount(
                            QxAccount(
                                (ll_account.getChildAt(0) as EditText).text.toString(),
                                (ll_account.getChildAt(1) as EditText).text.toString(),
                                (ll_account.getChildAt(2) as EditText).text.toString(),
                                (ll_account.getChildAt(3) as EditText).text.toString(),
                            )
                        )
                    }

                    RtkComponentType.SIXENTS -> {
                        val sixRtkManager =
                            getProduct()?.rtkManager?.netWorkRtkManager as SixentsRtkManager
                        sixRtkManager.setAccount(
                            SixentsAccount(
                                (ll_account.getChildAt(0) as EditText).text.toString(),
                                (ll_account.getChildAt(1) as EditText).text.toString(),
                                (ll_account.getChildAt(2) as EditText).text.toString(),
                                (ll_account.getChildAt(3) as EditText).text.toString(),
                            )
                        )
                    }

                    else -> {}
                }
            }.onFailure {
                showToast("save error, pls check input params.")
            }.onSuccess {
                showToast("save success.")
            }
        }
    }

    private fun initSDK() {
        msdkInfoVm.msdkInfo.observe(viewLifecycleOwner) {
            sw_rtk_enable.isEnabled = it.isAircraftConnected
            rg_rtk_component.isEnabled = it.isAircraftConnected

            if (it.isAircraftConnected) {
                refreshRtkEnable(getProduct()?.rtkManager?.rtkEnable ?: false)
                getProduct()?.rtkManager?.rtkComponentType?.let { rtkType ->
                    refreshRtkComponentType(rtkType)
                    refreshAccountView(rtkType)
                }
                getProduct()?.rtkManager?.setRtkStateListener { rtkInfo ->
                    tv_rtk_state.text = gson.toJson(rtkInfo)
                }
            }
        }
    }

    override fun onDestroyView() {
        getProduct()?.rtkManager?.setRtkStateListener(null)
        msdkInfoVm.msdkInfo.removeObservers(viewLifecycleOwner)
        super.onDestroyView()
    }

    private fun refreshRtkComponentType(rtkType: RtkComponentType) {
        when (rtkType) {
            RtkComponentType.NONE -> rb_rtk_type_none.isChecked = true
            RtkComponentType.QX -> rb_rtk_type_qx.isChecked = true
            RtkComponentType.CMCC -> rb_rtk_type_cmcc.isChecked = true
            RtkComponentType.SIXENTS -> rb_rtk_type_sixents.isChecked = true
            RtkComponentType.CUSTOM -> rb_rtk_type_custom.isChecked = true
            else -> {}
        }
    }

    private fun refreshAccountView(rtkType: RtkComponentType) {
        ll_account.removeAllViews()

        val javaClassType = when (rtkType) {
            RtkComponentType.CMCC -> CmccAccount::class.java
            RtkComponentType.QX -> QxAccount::class.java
            RtkComponentType.SIXENTS -> SixentsAccount::class.java
            RtkComponentType.CUSTOM -> NtripClientAccount::class.java
            RtkComponentType.NONE -> null
            else -> {null}
        }

        javaClassType?.let {javaClass ->
            for (field in javaClass.declaredFields) {
                if (field.name == "CREATOR") continue
                field.isAccessible = true
                val edt = EditText(requireContext()).also {edittext ->
                    edittext.hint = field.name
                    getProduct()?.rtkManager?.netWorkRtkManager?.account?.let { edittext.setText(field.get(it).toString()) }
                }
                ll_account.addView(edt)
            }
        }
    }

    private fun refreshRtkEnable(enable: Boolean) {
        sw_rtk_enable.isChecked = enable
    }
}